﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace P2PWeb.Common
{
    public class DateTimeGreaterDateTimeNow : ValidationAttribute, IClientValidatable
    {
        string errorMessage = "{0}必须大于当前时间";
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
            {
                return ValidationResult.Success;
            }
            else
            {
                return  ((DateTime)value)>=DateTime.Now.Date?ValidationResult.Success:
                     new ValidationResult(string.Format(errorMessage,validationContext.DisplayName));
            }
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
                                              ModelMetadata metadata,
                                              ControllerContext context)
        {
            var clientValidationRule = new ModelClientValidationRule()
            {
                ErrorMessage =string.Format(errorMessage,metadata.DisplayName),
                ValidationType = "datetimegreaterdatetimenow"//这里是核心点
            };

            yield return clientValidationRule;
        }
    }

    public class DateTimeGreaterDateTime : ValidationAttribute, IClientValidatable
    {
        private const string DefaultErrorMessage = "{0} 必须大于 {1}";

        private string _otherTimePropertyName = null;

        public DateTimeGreaterDateTime(string otherTimePropertyName)
            : base(DefaultErrorMessage)
        {

            _otherTimePropertyName = otherTimePropertyName;
        }

        public override string FormatErrorMessage(string name)
        {
            return DefaultErrorMessage;
        }

        public static string GetDisplayName(System.Reflection.PropertyInfo property)
        {
            var displayNameAttribute = property.GetCustomAttributes(false).First(f => f is DisplayNameAttribute);
            return (displayNameAttribute as DisplayNameAttribute).DisplayName;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                var otherTimeProperty = validationContext.ObjectInstance.GetType().GetProperty(_otherTimePropertyName);
                DateTime otherTime = Convert.ToDateTime(otherTimeProperty.GetValue(validationContext.ObjectInstance));
                DateTime curTime = (DateTime)value;
                if (curTime >= otherTime.AddDays(1).Date)
                {
                    return ValidationResult.Success;
                }
                string errorMessage = string.Format(FormatErrorMessage(null), validationContext.DisplayName, GetDisplayName(otherTimeProperty));
                return new ValidationResult(errorMessage);
            }
            else
            {
                return ValidationResult.Success;
            }
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
                                                      ModelMetadata metadata,
                                                      ControllerContext context)
        {
            var otherTimeProperty = metadata.ContainerType.GetProperty(_otherTimePropertyName);

            var clientValidationRule = new ModelClientValidationRule()
            {
                ErrorMessage = string.Format(FormatErrorMessage(null), metadata.DisplayName, GetDisplayName(otherTimeProperty)),
                ValidationType = "datetimegreaterdatetime"//这里是核心点
            };

            clientValidationRule.ValidationParameters.Add("ot", _otherTimePropertyName);

            yield return clientValidationRule;
        }
    }

    public class DateTimeRangeByStartTimeAndEndTime: ValidationAttribute, IClientValidatable
    {
        private const string DefaultErrorMessage = "{0} 必须大于 {1} 并且小于 {2}";

        private string _startTimePropertyName = null;
        private string _endTimePropertyName = null;

        public DateTimeRangeByStartTimeAndEndTime(string startTimePropertyName, string endTimePropertyName)
            : base(DefaultErrorMessage)
        {

            _startTimePropertyName = startTimePropertyName;
            _endTimePropertyName = endTimePropertyName;
        }

        public override string FormatErrorMessage(string name)
        {
            return DefaultErrorMessage;
        }

        public static string GetDisplayName(System.Reflection.PropertyInfo property)
        {
            var displayNameAttribute = property.GetCustomAttributes(false).First(f => f is DisplayNameAttribute);
            return (displayNameAttribute as DisplayNameAttribute).DisplayName;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                var startTimeProperty = validationContext.ObjectInstance.GetType().GetProperty(_startTimePropertyName);
                var endTimeProperty = validationContext.ObjectInstance.GetType().GetProperty(_endTimePropertyName);
                DateTime startTime = Convert.ToDateTime(startTimeProperty.GetValue(validationContext.ObjectInstance));
                DateTime endTime = Convert.ToDateTime(endTimeProperty.GetValue(validationContext.ObjectInstance));
                DateTime curTime = (DateTime)value;
                if (curTime > startTime && curTime < endTime)
                {
                    return ValidationResult.Success;
                }
                string errorMessage = string.Format(FormatErrorMessage(null), validationContext.DisplayName, GetDisplayName(startTimeProperty), GetDisplayName(endTimeProperty));
                return new ValidationResult(errorMessage);
            }
            else
            {
                return ValidationResult.Success;
            }
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
                                                      ModelMetadata metadata,
                                                      ControllerContext context)
        {
            var startTimeProperty = metadata.ContainerType.GetProperty(_startTimePropertyName);
            var endTimeProperty = metadata.ContainerType.GetProperty(_endTimePropertyName);

            var clientValidationRule = new ModelClientValidationRule()
            {
                ErrorMessage = string.Format(FormatErrorMessage(null), metadata.DisplayName, GetDisplayName(startTimeProperty), GetDisplayName(endTimeProperty)),
                ValidationType = "datetimerangebystarttimeandendtime"//这里是核心点
            };

            clientValidationRule.ValidationParameters.Add("s1", _startTimePropertyName);
            clientValidationRule.ValidationParameters.Add("e1", _endTimePropertyName);

            yield return clientValidationRule;
        }
    }
}